﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Web;
using System.Xml.Linq;

namespace mscook.core.services
{
    public class ImageSettingFactory : mscook.core.services.IImageSettingFactory
    {
        private XDocument imageSettingDocument;
        //private bool ifXMLDocumentExists = false;
        //private bool isImageFolderCreated = false;
        public static readonly string WIDE_FOLDER = "wide";
        public static readonly string DEFAULT_FOLDER = "default";
        public static readonly string PAD_FOLDER = "pad";
        public static readonly string MOBILE_FOLDER = "mobile";
        public static readonly string THUMB_FOLDER = "thumb";
        public static readonly string IMAGE_SETTING_FILE = "ImageSetting.xml";
        public static XNamespace ns = "http://chu.sh";
        public static readonly string[] SECTIONS = { "Slide", "Bulletin", "Chef", "Hotel", "Material", "Magzine", "Article","CookBook","BottomHotel" };
        private string uploadFolderPath;
        public string UploadFolderPath
        {
            get
            {
                return uploadFolderPath;
            }
        }
        public ImageSettingFactory()
        {
            this.uploadFolderPath = GetUploadFolderPath();

            if (!CheckIfXMLDocumentExists())
                CreateXMLDocument();
            else
                LoadXMLDocument();
            EnsureImageFolderCreated();
            if (!CheckIsImageFolderCreated(WIDE_FOLDER)
                ||
                !CheckIsImageFolderCreated(DEFAULT_FOLDER)
                ||
                !CheckIsImageFolderCreated(PAD_FOLDER)
                ||
                !CheckIsImageFolderCreated(MOBILE_FOLDER)
                 ||
                !CheckIsImageFolderCreated(THUMB_FOLDER)
                )
                throw new DirectoryNotFoundException("文件夹创建失败");


        }
        private string GetUploadFolderPath()
        {

            string uploadPath;
            if (HttpContext.Current != null)
            {
                uploadPath = HttpContext.Current.Server.MapPath("~/Upload");
            }
            else
            {
                uploadPath = AppDomain.CurrentDomain.BaseDirectory + "\\Upload";
            }

            if (!Directory.Exists(uploadPath))
            {
                Directory.CreateDirectory(uploadPath);
                if (!Directory.Exists(uploadPath))
                    throw new DirectoryNotFoundException("Upload文件夹创建失败");
            }
            return uploadPath + "\\";

        }
        public string ImageSettingFilePath
        {
            get
            {
                string xmlPath;
                if (HttpContext.Current != null)
                {
                    xmlPath = HttpContext.Current.Server.MapPath("~/Core/" + IMAGE_SETTING_FILE);
                }
                else
                {
                    xmlPath = AppDomain.CurrentDomain.BaseDirectory + "\\" + IMAGE_SETTING_FILE;
                }
                return xmlPath;
            }
        }
        /// <summary>
        /// 检查是否存在ImageSetting.xml文件   
        /// </summary>
        /// <returns></returns>
        private bool CheckIfXMLDocumentExists()
        {
            if (File.Exists(ImageSettingFilePath))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        /// <summary>
        /// 创建空Root列表
        /// </summary>
        /// <returns></returns>
        public bool CreateXMLDocument()
        {
            XDocument doc = new XDocument(
                // XML declaration
            new XDeclaration("1.0", "uft-8", "yes"),
                // The root element
            new XElement(ns + "Root")
            );

            // Save the XML document to file system
            doc.Save(ImageSettingFilePath);
            imageSettingDocument = doc;
            return true;
        }
        public void LoadXMLDocument()
        {
            imageSettingDocument = XDocument.Load(ImageSettingFilePath);
        }
        public void EnsureImageFolderCreated()
        {
            if (!CheckIsImageFolderCreated(WIDE_FOLDER))
                CreateImageFolder(WIDE_FOLDER);
            if (!CheckIsImageFolderCreated(DEFAULT_FOLDER))
                CreateImageFolder(DEFAULT_FOLDER);
            if (!CheckIsImageFolderCreated(PAD_FOLDER))
                CreateImageFolder(PAD_FOLDER);
            if (!CheckIsImageFolderCreated(MOBILE_FOLDER))
                CreateImageFolder(MOBILE_FOLDER);
            if (!CheckIsImageFolderCreated(THUMB_FOLDER))
                CreateImageFolder(THUMB_FOLDER);
        }
        private bool CheckIsImageFolderCreated(string folder)
        {
            string path = uploadFolderPath + folder;
            if (Directory.Exists(path))
            {
                return true;
            }
            else
            {
                return false;
            }
        }
        private bool CreateImageFolder(string folder)
        {
            string path = uploadFolderPath + folder;
            Directory.CreateDirectory(path);
            if (!Directory.Exists(path))
                throw new DirectoryNotFoundException(folder + "文件夹创建失败");
            return true;
        }
        private string generateNewImageName(string fileOldName)
        {
            string fileoldName = "";
            string fileExtension;
            string filesnewName = "";
            string filesNewNameWithoutExt = "";
            fileoldName = System.IO.Path.GetFileName(fileOldName);
            fileExtension = System.IO.Path.GetExtension(fileoldName).ToLower();
            Random R = new Random();//创建产生随机数
            int val = 10 + R.Next(999);//产生随机数为99以内任意
            int val1 = 10 + R.Next(999);//产生随机数为999以内任意
            filesNewNameWithoutExt = DateTime.Now.ToString("yyyyMMddHHmmss") + val.ToString() + val1.ToString();
            filesnewName = filesNewNameWithoutExt + fileExtension;
            return filesnewName;
        }
        /// <summary>
        /// 按照指定size生成到指定路径的图片的方法
        /// </summary>
        /// <param name="width"></param>
        /// <param name="height"></param>
        /// <param name="folder"></param>
        /// <param name="imageName">待扩展名的图片名</param>
        private void CreateSizedImage(int width, int height, string folder, string imageName)
        {
            System.Drawing.Image originalImage = System.Drawing.Image.FromFile(this.uploadFolderPath + imageName);

            int x = 0;
            int y = 0;
            int ow = originalImage.Width;
            int oh = originalImage.Height;

            //新建一个bmp图片
            System.Drawing.Image bitmap = new System.Drawing.Bitmap(width, height);

            //新建一个画板
            Graphics g = System.Drawing.Graphics.FromImage(bitmap);

            //设置高质量插值法
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;

            //设置高质量,低速度呈现平滑程度
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;

            //清空画布并以透明背景色填充
            g.Clear(Color.Transparent);

            //在指定位置并且按指定大小绘制原图片的指定部分
            g.DrawImage(originalImage, new Rectangle(0, 0, width, height),
             new Rectangle(x, y, ow, oh),
             GraphicsUnit.Pixel);

            try
            {
                //以jpg格式保存缩略图
                string genaratePicPath = this.uploadFolderPath + folder + "\\" + imageName;
                switch (System.IO.Path.GetExtension(genaratePicPath).ToLower())
                {
                    case ".gif": bitmap.Save(genaratePicPath, System.Drawing.Imaging.ImageFormat.Gif); break;
                    case ".jpg": bitmap.Save(genaratePicPath, System.Drawing.Imaging.ImageFormat.Jpeg); break;
                    case ".bmp": bitmap.Save(genaratePicPath, System.Drawing.Imaging.ImageFormat.Bmp); break;
                    case ".png": bitmap.Save(genaratePicPath, System.Drawing.Imaging.ImageFormat.Png); break;
                }
                //result = ((result == "") ? "" : result + ";") + "/uploadimage/" + ParentPath + "/" + filesnewName + "_" + size + "x" + size + fileExtension;

            }
            catch (System.Exception e)
            {
                throw e;
            }
            finally
            {
                bitmap.Dispose();
                g.Dispose();
            }
            originalImage.Dispose();

        }
        /// <summary>
        /// 按照指定版块图片设置生成不同尺寸的方法
        /// </summary>
        /// <param name="section"></param>
        /// <param name="imageName"></param>
        /// <param name="imageStream"></param>
        /// <returns>返回新创建的图片名称</returns>
        public string CreateBatchSizedImage(string section, string imageName, Stream imageStream)
        {
            string newImageName = generateNewImageName(imageName);
            ImageSettingSection imageSettingSection = SelectSection(section);
            //using (FileStream file = new FileStream(this.uploadFolderPath+newImageName, FileMode.Create, System.IO.FileAccess.Write))
            //{
            //    byte[] bytes = new byte[imageStream.Length];
            //    imageStream.Read(bytes, 0, (int)imageStream.Length);
            //    file.Write(bytes, 0, bytes.Length);
            //    imageStream.Close();
            //    file.Close();
            //}
            Image image = Image.FromStream(imageStream);
            image.Save(this.uploadFolderPath + newImageName);
            foreach (ImageSetting imageSetting in imageSettingSection.ImageSettings)
            {
                CreateSizedImage(imageSetting.width, imageSetting.height, imageSetting.folder, newImageName);
            }
            return newImageName;
        }
        public bool SaveSection(ImageSettingSection section)
        {
            if (!IfSectionExists(section))
            {
                imageSettingDocument.Root.Add(
                          new XElement(ns + "Section",
                        new XAttribute("name", section.name),
                        new XAttribute("alias", section.alias),
                        from p in section.ImageSettings
                        select new XElement(ns + "Image",
                            new XAttribute("folder", p.folder),
                            new XAttribute("width", p.width),
                            new XAttribute("height", p.height)
                        )
                    )
                );
                imageSettingDocument.Save(ImageSettingFilePath);
            }
            else
            {
                throw new Exception("该版块图片设置已存在");
            }
            return false;
        }
        public bool IfSectionExists(ImageSettingSection section)
        {
            var count = (from p in imageSettingDocument.Root.Elements(ns + "Section")
                         where p.Attribute("alias").Value == section.alias
                         select p
                                 ).Count();
            if (count == 0)
                return false;
            else
                return true;
        }
        public void UpdateSection(ImageSettingSection section)
        {
            DeleteSection(section);
            imageSettingDocument.Root.Add(
                         new XElement(ns + "Section",
                       new XAttribute("name", section.name),
                       new XAttribute("alias", section.alias),
                       from p in section.ImageSettings
                       select new XElement(ns + "Image",
                           new XAttribute("folder", p.folder),
                           new XAttribute("width", p.width),
                           new XAttribute("height", p.height)
                       )
                   )
               );
            imageSettingDocument.Save(ImageSettingFilePath);
        }
        public void DeleteSection(ImageSettingSection section)
        {
            var element = (from p in imageSettingDocument.Root.Elements(ns + "Section")
                           where p.Attribute("alias").Value == section.alias
                           select p).Single();
            element.Remove();
            imageSettingDocument.Save(ImageSettingFilePath);
        }
        /// <summary>
        ///  提供检测返回未设置的板块列表
        /// </summary>
        /// <returns></returns>
        public String[] SelectUnSetSections()
        {
            var elements = (from p in imageSettingDocument.Root.Elements(ns + "Section")
                            select p.Attribute("alias").Value);
            //2013-10-20 basilwang 返回差集
            elements = SECTIONS.Except(elements);
            return elements.ToArray();
        }
        public ImageSettingSection SelectSection(string section)
        {
            var item = (from p in imageSettingDocument.Root.Elements(ns + "Section")
                        where p.Attribute("alias").Value == section
                        select new ImageSettingSection()
                        {
                            name = p.Attribute("name").Value,
                            alias = p.Attribute("alias").Value,
                            ImageSettings = (from q in p.Elements(ns + "Image")
                                             select new ImageSetting()
                                             {
                                                 folder = q.Attribute("folder").Value,
                                                 width = Int32.Parse(q.Attribute("width").Value),
                                                 height = Int32.Parse(q.Attribute("height").Value)
                                             }).ToList()

                        }).SingleOrDefault();
            return item;
        }
        public IList<ImageSettingSection> SelectSections()
        {
            var list = (from p in imageSettingDocument.Root.Elements(ns + "Section")
                        select new ImageSettingSection()
                        {
                            name = p.Attribute("name").Value,
                            alias = p.Attribute("alias").Value,
                            ImageSettings = (from q in p.Elements(ns + "Image")
                                             select new ImageSetting()
                                             {
                                                 folder = q.Attribute("folder").Value,
                                                 width = Int32.Parse(q.Attribute("width").Value),
                                                 height = Int32.Parse(q.Attribute("height").Value)
                                             }).ToList()

                        }).ToList();
            return list;
        }
        public class ImageSettingSection
        {
            public ImageSettingSection()
            {
                this.ImageSettings = new List<ImageSetting>();
            }
            public string name
            {
                get;
                set;
            }
            public string alias
            {
                get;
                set;
            }
            public IList<ImageSetting> ImageSettings
            {
                get;
                set;
            }
            public void addImageSetting(ImageSetting imageSetting)
            {
                this.ImageSettings.Add(imageSetting);
            }
            public void removeImageSetting(ImageSetting imageSetting)
            {
                this.ImageSettings.Remove(imageSetting);
            }
        }
        public class ImageSetting
        {
            public string folder
            {
                get;
                set;
            }
            public int width
            {
                get;
                set;
            }
            public int height
            {
                get;
                set;
            }
        }
    }
}
